import nltk
import random
import re
import random
from telebot                         import TeleBot
from nltk.tokenize                   import word_tokenize
from nltk.stem                       import PorterStemmer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise        import cosine_similarity
from sklearn.ensemble                import RandomForestClassifier
from nltk.classify.scikitlearn       import SklearnClassifier

def match_pattern(user_input, pattern): 
    return re.match(pattern, user_input, re.IGNORECASE) is not None

def choose_random_response(response_list):
    return random.choice(response_list)

# Пример данных для обучения
training_data = [
    (r'Привет', ['Привет!', 'Здравствуй!']), 
    (r'Кто гей?', ['Я!', 'Ну конечно же ты!']), 
    ('Как дела?', ['Хорошо, спасибо!']),
    ('Что нового?', ['Не так много, как я хотел бы, но всё в порядке.']),
    ('Как тебя зовут?', ['FireBot!', 'Я Firebot!', 'Меня зовут Firebot!']),
    ('Что ты умеешь?', ['Я простой бот, который может отвечать на вопросы. Но не на всё я ещё учусь!']),
    # Добавьте свои вопросы и ответы
]

# Подготовка данных
def prepare_data(data):
    documents = []
    responses = []

    stemmer = PorterStemmer()

    for text, response_list in data:
        words = [stemmer.stem(word.lower()) for word in word_tokenize(text) if word.isalpha()]
        documents.append(' '.join(words))
        responses.append(response_list)

    return documents, responses

# Создание и обучение модели
X_train, y_train = prepare_data(training_data)
vectorizer = TfidfVectorizer()
X_train_tfidf = vectorizer.fit_transform(X_train)

# Функция для получения ответа от бота
def get_response(user_input):
    user_input = ' '.join([PorterStemmer().stem(word.lower()) for word in word_tokenize(user_input) if word.isalpha()])
    user_input_tfidf = vectorizer.transform([user_input])

    # Поиск наилучшего совпадения
    best_match_index = max(range(len(X_train)), key=lambda i: cosine_similarity(user_input_tfidf, X_train_tfidf[i]))

    if cosine_similarity(user_input_tfidf, X_train_tfidf[best_match_index]) > 0.5:
        response_list = y_train[best_match_index]
        chosen_response = choose_random_response(response_list)
        return chosen_response
    else:
        # Добавьте обработку паттернов для вариаций фраз
        for pattern, response_list in training_data:
            if match_pattern(user_input, pattern):
                chosen_response = choose_random_response(response_list)
                return chosen_response

        return "Извините, я не знаю ответа на этот вопрос. Я только начинаю обучаться"
        

def update_and_add_data(training_data, new_data):
    global X_train, y_train, X_train_tfidf, vectorizer

    stemmer = PorterStemmer()

    # Добавление новых данных в обучающие данные
    for text, response_list in new_data:
        words = [stemmer.stem(word.lower()) for word in word_tokenize(text) if word.isalpha()]
        X_train.append(' '.join(words))
        y_train.append(response_list)

    # Обновление модели и разреженной матрицы
    X_train_tfidf = vectorizer.fit_transform(X_train)

# Пример новых данных для обновления модели
new_training_data = [
    ('Как провести выходные?', ['Можно пойти на прогулку, почитать книгу, посмотреть фильм.']),
    ('Что посоветуешь почитать?', ['Могу порекомендовать классику или актуальные бестселлеры.']),
    # Добавьте свои новые вопросы и ответы
]

# Обновление модели с новыми данными
update_and_add_data(training_data, new_training_data)


def set_message_handler(bot: TeleBot):
       
    @bot.message_handler(commands=['bot'])
    def handle_bot_command(message):
        # Извлекаем текст после команды /bot
        user_input = message.text[len('/bot '):].strip()
    
        if user_input.lower():
           
   
            response = get_response(user_input)
            bot.send_message(message.chat.id, f"{response}")        
            